package modeloCarmenSanDiego;

import java.util.*;

import modeloCarmenSanDiego.edificios.*;
import modeloCarmenSanDiego.pistas.*;

public class Ciudad {
	
	private double paralelo;
	private double meridiano;
	private String nombre;
	private List<Edificio> edificios = new ArrayList<Edificio>();
	private List<Ciudad> destinos = new ArrayList<Ciudad>();
	private Map<DificultadDePista, Map<Tema, String>> caracteristicas;
	
	public Ciudad(String nombre, double paralelo, double meridiano) {
		this.paralelo = paralelo;
		this.meridiano = meridiano;
		this.nombre = nombre;
		caracteristicas = new TreeMap<DificultadDePista, Map<Tema, String>>();
		caracteristicas.put(DificultadDePista.FACIL, new TreeMap<Tema, String>());
		caracteristicas.put(DificultadDePista.MEDIA, new TreeMap<Tema, String>());
		caracteristicas.put(DificultadDePista.DIFICIL, new TreeMap<Tema, String>());
		
	}
	
	public double getParalelo(){
		return paralelo;
	}

	public double getMeridiano(){
		return meridiano;
	}
	
	public String getNombre(){
		return nombre;
	}
	
	public List<Ciudad> getDestinos(){
		return destinos;
	}

	public void addDestino(Ciudad ciudad) {
		if (ciudad.getNombre() != this.nombre)	
			//una ciudad no se puede tener a si misma como destino
			this.destinos.add(ciudad);
		//Collections.shuffle(this.destinos);
	}

	public void addEdificio(Edificio edificio) {
		this.edificios.add(edificio);
	}

	public List<Edificio> getEdificios() {
		return this.edificios;
	}
	
	public int distanciaA(Ciudad otraCiudad){
		//fuente: http://cutnpaste.org/blog/java-calcular-distancia-entre-dos-latitudes-y-longitudes/
		double radioDeLaTierraEnKm = 6371; 
        double variacionLatitud = Math.toRadians( otraCiudad.getParalelo() - this.paralelo );  
        double variacionLongitud = Math.toRadians( otraCiudad.getMeridiano() - this.meridiano );  
        double senoVariacionLatitud = Math.sin( variacionLatitud / 2);  
        double senoVariacionLongitud = Math.sin( variacionLongitud / 2);  
        double terminoA = Math.pow( senoVariacionLatitud, 2 ) + Math.pow( senoVariacionLongitud, 2)  
                * Math.cos(Math.toRadians( this.paralelo )) * Math.cos(Math.toRadians( otraCiudad.getParalelo() ));  
        double terminoC = 2 * Math.atan2(Math.sqrt(terminoA), Math.sqrt(1 - terminoA));  
        double distancia = radioDeLaTierraEnKm * terminoC;  
  
        return (int) Math.floor(distancia);  
	}

	public void addCaracteristica(DificultadDePista dificultad, Tema tema, String stringDeCaracteristica){
		(this.caracteristicas.get(dificultad)).put(tema, stringDeCaracteristica);
	}
	
	public Map<DificultadDePista, Map<Tema, String>> getCaracteristicas() {
		return caracteristicas;
	}

	public void resetearDestinos() {
		this.destinos = new ArrayList<Ciudad>();
	}

	public void mezclarDestinos() {
		Collections.shuffle(destinos);
		
	}
	
}
